/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package yuhuibear.poat.object.pipe;

import javax.sql.DataSource;

import yuhuibear.poat.object.bean.BeanConstructor;
import yuhuibear.poat.object.bean.PersistentClassLoader;
import yuhuibear.poat.object.mapEntity.DataBaseMapper;
import yuhuibear.poat.query.ParamArranger;

/**
 * 管理数据库连接管道的对象。<br>
 * 是系统启动对象。
 * 
 * @author yuhui_bear
 */
public class POAT {

	/**
	 * 直接来自jdbc驱动的，不经第三方连接管理。以便支持驱动专有的操作。
	 */
	private DataSource directSource;

	/**
	 * 能够操schema的。
	 */
	private DataSource schemaSource;

	/**
	 * 只有最低权限，仅能够进行普通的查插删改。
	 */
	private DataSource userSource;

	private BeanConstructor bConstructor;

	private ParamArranger pramSetter;

	private PersistentClassLoader structfactory;

	/**
	 * 根据数据原 @see DataSource 初始化系统。
	 * 
	 * @param db
	 *            , 同时被指向directSource， userSource, schemaSource.
	 * @throws java.lang.Exception
	 */
	public POAT(DataSource db) throws Exception {
		directSource = db;
		schemaSource = db;
		userSource = db;
		structfactory = PersistentClassLoader.getInstance();
		bConstructor = new BeanConstructor(structfactory);
		pramSetter = new ParamArranger(structfactory, directSource);
	}

	/**
	 * 根据数据原 DataSource 初始化系统。
	 * 
	 * @param db
	 *            , 同时被指向directSource， userSource, schemaSource.
	 * @param entityPackage
	 *            bean 所在的包名。
	 * @throws java.lang.Exception
	 */
	public POAT(DataSource db, String entityPackage) throws Exception {
		directSource = db;
		schemaSource = db;
		userSource = db;
		structfactory = PersistentClassLoader.getInstance();
		structfactory.scanPackage(entityPackage);
		bConstructor = new BeanConstructor(structfactory);
		pramSetter = new ParamArranger(structfactory, directSource);
	}

	public POAT(DataSource directSource, DataSource userSource,
			DataSource schemaSouce, String entityPackage) throws Exception {
		this.directSource = directSource;
		this.schemaSource = schemaSouce;
		this.userSource = userSource;
		structfactory = PersistentClassLoader.getInstance();
		structfactory.scanPackage(entityPackage);
		bConstructor = new BeanConstructor(structfactory);
		pramSetter = new ParamArranger(structfactory, directSource);
	}

	/**
	 * 扫描并解析指定的包。这样可以避免查询的时候再次解析。
	 * 
	 * @param entityPackage
	 * @return
	 * @throws java.lang.Exception
	 */
	public int scanEntity(String entityPackage) throws Exception {
		return structfactory.scanPackage(entityPackage);
	}

	/**
	 * 扫描指定包，并将所有具有数据库描述标签的对象， 创建为对数据库中的表。
	 * 
	 * @param clear
	 *            是否清除现有的数据库架构
	 * @return
	 * @throws java.lang.Exception
	 */
	public int mapAllEntities(boolean clear) throws Exception {
		DataBaseMapper mapper = new DataBaseMapper(structfactory.getAllStructs());
		return mapper.createTable(schemaSource.getConnection(), clear);
	}

	/**
	 * 获取一个对象访问管道 @see ObjectAccessPipe
	 * 
	 * @return 从指定数据源返回管道。
	 * @throws java.lang.Exception
	 */
	public ObjectAccessPipe getPipe() throws Exception {
		ObjectAccessPipe pipe = new ObjectAccessPipeImpl(userSource.getConnection(), null, bConstructor, structfactory, pramSetter);
		return pipe;
	}

	/**
	 * 以指定的事务隔离度获取管道。
	 * 
	 * @param transanctionIsolation
	 *            , 来自 java.sql.Connection
	 * @return
	 * @throws java.lang.Exception
	 */
	public ObjectAccessPipe getPipe(Integer transanctionIsolation)
			throws Exception {
		ObjectAccessPipe pipe = new ObjectAccessPipeImpl(userSource.getConnection(), transanctionIsolation, bConstructor, structfactory, pramSetter);
		return pipe;
	}

	/**
	 * 直接来自jdbc驱动的，不经第三方连接管理。以便支持驱动专有的操作。
	 * 
	 * @return the directSource
	 */
	public DataSource getDirectSource() {
		return directSource;
	}

	/**
	 * 直接来自jdbc驱动的，不经第三方连接管理。以便支持驱动专有的操作。
	 * 
	 * @param directSource
	 *            the directSource to set
	 */
	public void setDirectSource(DataSource directSource) {
		this.directSource = directSource;
	}

	/**
	 * 能够操schema的。
	 * 
	 * @return the schemaSource
	 */
	public DataSource getSchemaSource() {
		return schemaSource;
	}

	/**
	 * 能够操schema的。
	 * 
	 * @param schemaSource
	 *            the schemaSource to set
	 */
	public void setSchemaSource(DataSource schemaSource) {
		this.schemaSource = schemaSource;
	}

	/**
	 * 只有最低权限，仅能够进行普通的查插删改。
	 * 
	 * @return the userSource
	 */
	public DataSource getUserSource() {
		return userSource;
	}

	/**
	 * 只有最低权限，仅能够进行普通的查插删改。
	 * 
	 * @param userSource
	 *            the userSource to set
	 */
	public void setUserSource(DataSource userSource) {
		this.userSource = userSource;
	}

}
